﻿/**
 * @brief     Tcp客户端 - 同步方式通讯
 * @details   1、创建Tcp客户端
 * @author    Will.Yin
 * @version   1.0
 * @date      2021-07-08
 * @copyright
 * @note
 */
#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include "common_global.h"

#include <QObject>
#include <QAbstractSocket>
#include <QHostAddress>
#include <QTcpSocket>
#include <QHostInfo>

#define TCPCLIEBT_REPLY_TIMEOUT   3000

namespace Common {

	class COMMONSHARED_EXPORT TcpClient : public QObject
	{
		Q_OBJECT

	public:
		explicit TcpClient(QObject *parent = Q_NULLPTR);
		~TcpClient();

	public:

		/**
		 * @brief getTcpSocket 获取 TcpSocket
		 * @return
		 */
		QTcpSocket * getTcpSocket();

		/**
		 * @brief connectToServer 连接服务器
		 * @param localPort  本地端口
		 * @param strTargetIp 目标Ip
		 * @param targetPort 目标端口
		 * @param retryTimes 连接次数
		 * @return
		 */
		bool connectToServer(int localPort, QString strTargetIp, int targetPort, const int retryTimes = 3);

		/**
		 * @brief connectToServer 连接服务器
		 * @param strTargetIp 目标Ip
		 * @param targetPort 目标端口
		 * @param retryTimes 连接次数
		 * @return
		 */
		bool connectToServer(QString strTargetIp, int targetPort, const int retryTimes = 3);

		/**
		 * @brief disconnectFromServer 断开连接
		 * @return
		 */
		bool disconnectFromServer();

		/**
		 * @brief  isConnected 检测TCP是否连接
		 * @return bool
		 */
		bool isConnected();

		/**
		 * @brief  sendTcplMsg 发送TCP消息
		 * @param  message 消息内容
		 * @return bool
		 */
		bool sendTcpMsg(QByteArray message);

		/**
		 * @brief  recvTcplMsg 接收TCP消息
		 * @param  message 消息内容
		 * @param  replyTime 超时时间
		 * @return bool
		 */
		bool recvTcpMsg(QByteArray &message, const int replyTime = TCPCLIEBT_REPLY_TIMEOUT);

		/**
		 * @brief  sendAndRecvTcpMsg 发送和接收tcp报文
		 * @param  sendMsg 发送消息内容
		 * @param  recvMsg 接受消息内容
		 * @param  replyTime 超时时间
		 * @return bool
		 */
		bool sendAndRecvTcpMsg(const QByteArray sendMsg, QByteArray &recvMsg, const int replyTime = TCPCLIEBT_REPLY_TIMEOUT);

		/**
		 * @brief  clear 清理缓冲区数据
		 * @return void
		 */
		void clear();

	Q_SIGNALS:
		/**
		 * @brief signalTcpClientError 发送客户端异常消息
		 * @param strError
		 */
		void signalTcpClientError(QString strError);

	private Q_SLOTS:
		/**
		 * @brief slotTcpSocketStateChange 查看网络状态
		 * @param state
		 */
		void slotTcpSocketStateChange(QAbstractSocket::SocketState state);

	private:
		QTcpSocket * m_tcpSocket;           // 套接字

	};

}//namespace Common

#endif // TCPCLIENTTHREAD_H
